// Copyright (c) 2021 Presto Labs Pte. Ltd.
// Author: hyuan

#pragma once

#include <cstdio>
#include <memory>
#include <set>
#include <string>
#include <unordered_map>

#include <rapidjson/document.h>

#include "coin2/exchange/base/order/order.h"
#include "coin2/exchange/deribit_base/api_util/rate_tracker.h"
#include "coin2/exchange/deribit_futures/symbology/currency.h"
#include "coin2/exchange/deribit_futures/symbology/product.h"

namespace coin2::exchange::deribit_futures::order_v2 {

class DeribitOptionsParser : public base::order::BaseParser {
 public:
  DeribitOptionsParser();
  const ParseResult& ParseRawMessage(const RawMessage& msg) override;
  AccountBalance ParseBalance(const JsonValue& doc) override;
  AccountPosition ParsePosition(const JsonValue& doc) override;

 private:
  void ParseListenKey();
  void ParseSubmitResponse();
  void ParseCancelResponse();
  void ParseRestAuthToken();
  std::string ParseAuthToken(const JsonValue& doc);

  void ParseRestAccounts();
  void ParseRestFillInfoList();
  void ParseRestAccountBalance();
  void ParseRestAccountPosition();
  void ParseWsMessage();

  // Handle FIX message.
  void ParseFixMessage();
  void ParseFixSubmitResponse(const FIX::Message& message);
  void ParseFixCancelResponse(const FIX::Message& message);
  void ParseFixFillInfo(const FIX::Message& message);
  void ParseFixOrderInfo(const FIX::Message& message);
  void ParseFixSecurityList(const FIX::Message& message);
  void ParseRestOrderInfoList();
  bool ParseWsPositionFromChanges(const JsonValue& doc, AccountPosition* acc_position);
  bool ParseWsOrderFromChanges(const JsonValue& doc, ProductOrderBundle* product_order_bundle);
  bool ParseWsTradeFromChanges(const JsonValue& doc, ProductFillBundle* product_fill_bundle);
  auto ParseRestOrderInfo(const JsonValue& data) -> coin::proto::ProductOrderElement;
  auto GetContractValue(const std::string& symbol) -> double;
  void SetContractValue(const std::string& symbol, double val);

 private:
  bool is_balance_initialized_{false};
  bool is_position_initialized_{false};
  std::unordered_map<std::string, coin::proto::CurrencyBalance> balance_map_;
  std::unordered_map<std::string, coin::proto::ProductPosition> position_map_;
  std::unordered_map<std::string, coin::proto::ProductPosition> undetected_position_map_;
  std::unordered_map<std::string, double> contract_value_map_;

  std::string currency_base_;
};

}  // namespace coin2::exchange::deribit_futures::order_v2
